package my.study.java.lang.ref;

import static org.junit.Assert.*;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;

import org.junit.Test;

public class Ex01 {
	/**
	 * 通过赋值创建 StrongReference，StrongReference 在 GC 后不会被回收
	 */
	@Test
	public void strongReference() {   
	     Object referent = new Object();     
	     Object strongReference = referent;   	      
	     assertSame(referent, strongReference);
	     referent = null;   
	     System.gc();
	     assertNotNull(strongReference);   
	}
	
	/**
     * 一旦没有指向 referent的强引用, weak reference在GC后会被自动回收
     */  
	@Test  
	public void weakReference() {   
	     Object referent = new Object();   
	     WeakReference<Object> weakRerference = new WeakReference<Object>(referent);   
	     assertSame(referent, weakRerference.get());   
	     referent = null;   
	     System.gc();   
	     assertNull(weakRerference.get());   
	}

    /**
     * 等待无效 entries进入 ReferenceQueue以便下一次调用 getTable时被清理
     * 一旦没有指向 key的强引用, WeakHashMap在GC后将自动删除相关的 entry
     */  
	@Test  
	public void weakHashMap() throws InterruptedException {   
	     Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>();   
	     Object key = new Object();   
	     Object value = new Object();   
	     weakHashMap.put(key, value); 
	     assertTrue(weakHashMap.containsValue(value));   
	     key = null;   
	     System.gc();   
	     Thread.sleep(1000);   
	     assertFalse(weakHashMap.containsValue(value));   
	}
	
	
	/**
     * soft references 只有在 jvm OutOfMemory 之前才会被回收, 
     * 所以它非常适合缓存应用
     */  
	@Test  
	public void softReference() {   
	     Object referent = new Object();   
	     SoftReference<Object> softRerference = new SoftReference<Object>(referent);
	     assertNotNull(softRerference.get());      
	     referent = null;   
	     System.gc();   
	     assertNotNull(softRerference.get());   
	}   

	







}
